import Vue from "vue";
import Vuex from "vuex";
import * as types from "./types";

// 注册该组件
Vue.use(Vuex);

// 导出store实例
export default new Vuex.Store({
  // 这个state里面只能简单数据类型
  state: {
    num: 2,
    num2: 4,
    arr: [1,2,3,4],
    todos:[{title: "吃饭", done: true},{title: "睡觉", done: false}]
  }, //state状态


  // 就是这里先拿到state,并且筛选它，然后发送给home.vue中的computed中的doneTodos()
  // {return this.$store.getters.doneTodos},然后进行页面渲染
  getters:{
    doneTodos(state){
      // filter用于对数组进行过滤。
      // 它创建一个新数组，新数组中的元素是通过检查指定数组中符合条件的所有元素。
      return state.todos.filter(todo => todo.done) //相当于todo.done===true
    },
    filterTodos: state => (doneState) => state.todos.filter(todo => todo.done === doneState)
    // filterTodos(state){
      // 如果没有传值，就全部显示，如果是false,就返回睡觉，如果是true,就返回吃饭
    //   return function(done){
    //     if(done === undefined) return state.todos
    //     return state.todos.filter(todo => todo.done === done)
    //   }
    // }
  },
  mutations: {//改变，写方法，第一个参数state
    // 增加state中的num,vuex中对状态的改变，都是以自定义事件的形式
    // 写在mutations中的方法，相当于注册了一个和方法相同的自定义事件

    // 属性名表达式，[变量](){}
    [types.INCREMENT](state,payload){
      state.num  += payload
    },
    [types.CHANGE](state,payload){
      const {index,value} = payload;
      // 响应式是针对对象的，数组是没有响应式的,
      // 其实在vuex中的state里面的arr已经变成[1,2,100,,4],只是没有响应过去
      // 但是有上面 的increment的话，num是会有响应式的，所以会让页面重新渲染，拿到最新的值
      // state.arr[index] = value;

      // 数组的增强方法
      // splice() 方法用于添加或删除数组中的元素。
      // 注意：这种方法会改变原始数组。
      // 根据index,删除原值，删除一个，增加新值
      // state.arr.splice(index,1,value);

      // state中的数据，修改的值的下标，修改的值
      Vue.set(state.arr,index,value);

    }

  },
  actions: {
    // 参数context就是一个store实例的拷贝，所以就有commit方法
    // 可以和mutation中的名字重复
    // [types.INCREMENT](context){
    //   // 想改state中的数据，就要通过commit提交自定义事件，
    //   // 就是提交mutation中的自定义事件
    //   context.commit(types.INCREMENT,20)
    //   console.log(context);
    // }


     // 也可以直接对context对象进行解构， 拿出其中的commit方法
    // actions方法中的调用，也是通过提交事件的方式
    // 这里的 [types.INCREMENT]这个和下面的含义不一样，下面的是mutation中的
    // 为什么这两个可以一样呢，这个是用dispatch进行提交，下面的是commit进行提交
    [types.INCREMENT]({commit},payload){
      // actions中修改state 一定要通过 提交mutation的方式
      // 想改state中的数据，就要通过commit提交自定义事件，
      // 就是提交mutation中的自定义事件
      //  事件名称第一个参数
      // action中可以做任何的异步操作
      setTimeout(() => {
        commit(types.INCREMENT,payload.amount)
      }, 1000)
     
    }
  },
  modules: {},
});
